﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Tnelab.Miniblink
{
    public enum MouseFlags
    {
        LBUTTON = 0x01,
        RBUTTON = 0x02,
        SHIFT = 0x04,
        CONTROL = 0x08,
        MBUTTON = 0x10,
    }
    public enum KeyFlags
    {
        EXTENDED = 0x0100,
        REPEAT = 0x4000,
    }
    public enum MouseMsg
    {
        MOUSEMOVE = 0x0200,
        LBUTTONDOWN = 0x0201,
        LBUTTONUP = 0x0202,
        LBUTTONDBLCLK = 0x0203,
        RBUTTONDOWN = 0x0204,
        RBUTTONUP = 0x0205,
        RBUTTONDBLCLK = 0x0206,
        MBUTTONDOWN = 0x0207,
        MBUTTONUP = 0x0208,
        MBUTTONDBLCLK = 0x0209,
        MOUSEWHEEL = 0x020A,
    }
    public enum CursorType
    {
        Pointer,
        Cross,
        Hand,
        IBeam,
        Wait,
        Help,
        EastResize,
        NorthResize,
        NorthEastResize,
        NorthWestResize,
        SouthResize,
        SouthEastResize,
        SouthWestResize,
        WestResize,
        NorthSouthResize,
        EastWestResize,
        NorthEastSouthWestResize,
        NorthWestSouthEastResize,
        ColumnResize,
        RowResize,
        MiddlePanning,
        EastPanning,
        NorthPanning,
        NorthEastPanning,
        NorthWestPanning,
        SouthPanning,
        SouthEastPanning,
        SouthWestPanning,
        WestPanning,
        Move,
        VerticalText,
        Cell,
        ContextMenu,
        Alias,
        Progress,
        NoDrop,
        Copy,
        None,
        NotAllowed,
        ZoomIn,
        ZoomOut,
        Grab,
        Grabbing,
        Custom
    }
    public enum PostBodyElementType
    {
        Data, File,
    }
    public class PostBodyElementInfo
    {
        public PostBodyElementType ElementType { get; private set; }
        public byte[] Datas { get; private set; }
        public string FileName { get; private set; }
        public PostBodyElementInfo(PostBodyElementType elementType,byte[] datas,string fileName)
        {
            this.ElementType= elementType;
            this.Datas= datas;
            this.FileName= fileName;
        }
    }
    public class JsCallNativeEventArgs : EventArgs
    {
        public IWebView WebView { get; private set; }
        public long CallId { get; private set; }
        public int MessageId { get; private set; }
        public string Message { get; private set; }
        public object? Param { get; set; }
        public JsCallNativeEventArgs(IWebView webview,long callId,int messageId,string message)
        {
            this.WebView=webview;
            this.CallId=callId;
            this.MessageId=messageId;
            this.Message=message;
        }
    }
    public class Rect
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
    }
    public class PaintBitUpdatedEventArgs : EventArgs
    {
        public IWebView WebView { get; private set; }
        //public object Param { get; internal set; }
        public Stream Buffer { get; private set; }
        public Rect Rect { get; private set; }
        public int Width { get; private set; }
        public int Height { get; private set; }
        public PaintBitUpdatedEventArgs(IWebView webview,Stream buffer,Rect rect,int width,int height)
        {
            this.WebView= webview;
            this.Buffer=buffer;
            this.Rect=rect;
            this.Width=width;
            this.Height=height;
        }
    }
    public class PaintUpdatedEventArgs : EventArgs
    {
        public IWebView WebView { get; private set; }
        //public object Param { get; internal set; }
        public IntPtr Hdc { get; private set; }
        public int X { get; private set; }
        public int Y { get; private set; }
        public int Width { get; private set; }
        public int Height { get; private set; }
        public PaintUpdatedEventArgs(IWebView webview, IntPtr hdc, int x,int y, int width, int height)
        {
            this.WebView = webview;
            this.Hdc= hdc;
            this.X= x;
            this.Y= y;
            this.Width = width;
            this.Height = height;
        }
    }
    public class Size
    {
        public int Width { get; set; }
        public int Height { get; set; }
        public Size(int width, int height)
        {
            this.Width = width;
            this.Height = height;
        }
    }
    public class LoadUrlBeginEventArgs : EventArgs
    {
        public IWebView WebView { get; private set; }
        public string Url  { get; private set; }
        /// <summary>
        /// 可以用任意位置html填充
        /// </summary>
        public Stream? DataStream { get; set; }
        public PostBodyElementInfo[]? PostBodyElements { get; private set; }
        public LoadUrlBeginEventArgs(IWebView webview, string url, PostBodyElementInfo[]? postBodyElements=null)
        {
            this.WebView= webview;
            this.Url= url;
            this.PostBodyElements= postBodyElements;
        }
    }
    public class DocumentReadyEventArgs : EventArgs
    {
        public IntPtr FrameId { get;private set; }
        public DocumentReadyEventArgs(IntPtr frameId)
        {
            this.FrameId= frameId;
        }
    }
    public class LoadUrlEndEventArgs : EventArgs
    {
        public IWebView WebView { get; private set; }
        public string Url { get; private set; }
        /// <summary>
        /// 传回的内容指针
        /// </summary>
        public IntPtr Buffer { get; private set; }
        public int BufferLength { get; private set; }
        /// <summary>
        /// 用于覆盖传回的内容
        /// </summary>
        public Stream? DataStream { get; set; }
        public LoadUrlEndEventArgs(IWebView webView, string url, IntPtr buffer, int bufferLenght)
        {
            this.WebView=webView;
            this.Url = url;
            this.Buffer= buffer;
            this.BufferLength= bufferLenght;
        }
    }
    public class TitleChangedEventArgs : EventArgs
    {
        public string Title { get; private set; }
        public TitleChangedEventArgs(string title)
        {
            this.Title= title;
        }
    }
    public interface IWebView:IDisposable
    {
        event EventHandler<TitleChangedEventArgs>? TitleChanged;
        event EventHandler<LoadUrlBeginEventArgs>? LoadUrlBegin;
        event EventHandler<DocumentReadyEventArgs>? DocumentReady;
        event EventHandler<LoadUrlEndEventArgs>? LoadUrlEnd;
        event EventHandler<PaintUpdatedEventArgs>? PaintUpdated;
        event EventHandler<PaintBitUpdatedEventArgs>? PaintBitUpdated;
        event EventHandler<JsCallNativeEventArgs>? JsCallNative;
        IntPtr Handle { get; }
        /// <summary>
        /// 是否启用LoadUrlEnd事件
        /// </summary>
        bool LoadUrlEndEnable { get; set; }
        bool Transparent { get; set; }
        void LoadUrl(string url);
        bool IsVip { get; }
        Size Size { get; }
        void Resize(int width, int height);
        bool FireKeyDownEvent(uint virtualKeyCode, uint flags, bool systemKey);
        bool FireKeyUpEvent(uint virtualKeyCode, uint flags, bool systemKey);
        void SetFocus();
        void KillFocus();
        bool FireKeyPressEvent(uint virtualKeyCode, uint flags, bool systemKey);
        bool FireWindowsMessage(uint message,uint wParam, uint lParam, out int result);
        bool FireMouseWheelEvent(int x, int y, int delta, uint flags);
        bool FireMouseEvent(uint message, int x, int y, uint flags);
        void SetPosition(int x, int y);
        CursorType GetCursorType();
        void SetDebugConfig(string debuString, string param);
        Task<string?> RunJsAsync(string script);
        string? RunJs(string script);
        void ResponseJsCallNative(Int64 callId, int messageId, string response);
    }
}
